package com.dl698.asn1.axdr;

import com.dl698.util.ReverseByteArrayInputStream;
import com.dl698.util.ReverseByteArrayOutputStream;

import java.io.IOException;

/**
 * AXDR八位字节串类型
 * 实现字节数组的编解码
 * 
 * @author wind
 * @version 1.1.1
 */
public class AxdrOctetString implements AxdrType {

    private byte[] octetString = null;
    private int length = 0;

    /**
     * 默认构造函数
     */
    public AxdrOctetString() {
    }

    /**
     * 构造函数
     * 
     * @param octetString 字节数组
     */
    public AxdrOctetString(byte[] octetString) {
        setDataCode(octetString);
    }

    /**
     * 设置长度并分配内存
     * 
     * @param length 长度
     */
    public void setLength(int length) {
        this.length = length;
        this.octetString = new byte[length];
    }

    /**
     * 设置数据编码
     * 
     * @param octetString 字节数组
     */
    public void setDataCode(byte[] octetString) {
        if (octetString != null) {
            this.octetString = octetString;
            this.length = octetString.length;
        }
    }

    /**
     * 设置长度和数据
     * 
     * @param length      长度
     * @param octetString 字节数组
     */
    public void setAll(int length, byte[] octetString) {
        if (length != 0 && length != octetString.length) {
            throw new IllegalArgumentException("octetString of wrong size");
        }
        this.length = length;
        this.octetString = octetString;
    }

    @Override
    public int decode(ReverseByteArrayInputStream input) {
        try {
            int codeLength = 0;
            int len = this.length;

            if (len == 0) {
                AxdrLength l = new AxdrLength(0);
                codeLength += l.decode(input);
                len = l.getValue();
                this.octetString = new byte[len];
            }

            if (len != 0) {
                if (input.readOffset(this.octetString, 0, len) < len) {
                    throw new RuntimeException("Error Decoding AxdrOctetString");
                }
                codeLength += len;
            }

            return codeLength;
        } catch (IOException e) {
            throw new RuntimeException("Decode error", e);
        }
    }

    @Override
    public int encode(ReverseByteArrayOutputStream output) {
        try {
            int codeLength = 0;

            if (octetString != null) {
                output.writeByte(octetString);
                codeLength = octetString.length;

                if (length == 0) {
                    AxdrLength length = new AxdrLength(octetString.length);
                    codeLength += length.encode(output);
                }
            }

            return codeLength;
        } catch (IOException e) {
            throw new RuntimeException("Encode error", e);
        }
    }

    /**
     * 获取值
     * 
     * @return 字节数组
     */
    public byte[] getValue() {
        return octetString;
    }

    /**
     * 获取长度
     * 
     * @return 长度
     */
    public int getLength() {
        return length;
    }

    /**
     * 获取数据编码
     * 
     * @return 数据编码
     */
    public byte[] getDataCode() {
        return octetString;
    }

    @Override
    public String toString() {
        if (octetString == null) {
            return "";
        }

        StringBuilder s = new StringBuilder();
        for (byte b : octetString) {
            String hexString = Integer.toHexString(b & 0xFF);
            if (hexString.length() == 1) {
                s.append('0');
            }
            s.append(hexString);
        }
        return s.toString().toUpperCase();
    }
}